package com.WaVel.controller.admin;


import com.Emplyment.dto.QuestionBankDto;
import com.Emplyment.entity.QuestionBank;
import com.Emplyment.exception.BaseException;
import com.Emplyment.result.Result;
import com.Emplyment.util.CacheInterview;
import com.Emplyment.vo.QuestionBankVo;
import com.WaVel.service.InterviewQuestionsService;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Delete;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/interview")
@Slf4j
public class InterviewQuestionsController {

    @Autowired
    private InterviewQuestionsService interviewQuestionsService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private ObjectMapper objectmapper;

    private static final String INTERVIEW_HASH_KEY = "interview:HASH:data";
    private static final String INTERVIEW_HOT_DATA = "interview:ZSET:rank";

    private final String exchangeName = "interview_exchange";

    private final String addRoutingKey = "interview.add";

    private final String updateRoutingKey = "interview.update";

    private final String deleteRoutingKey = "interview.delete";

    @GetMapping("/questions")
    public Result<List<QuestionBankVo>> getQuestions() {
        log.info("获取所有面试问题");
        List<QuestionBankVo> questions = interviewQuestionsService.getQuestions();
        return Result.success(questions);
    }

    @PostMapping("/addQuestion")
    @Transactional
    public Result addQuestion(@RequestBody QuestionBankDto questionBankDto) {
        log.info("添加面试问题：{}",questionBankDto);
        try {
            CacheInterview cacheInterview = new CacheInterview();
            QuestionBank questionBank = interviewQuestionsService.addQuestion(questionBankDto);

            cacheInterview.setQuestionBank(questionBank);
            long expireTime = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(2);
            cacheInterview.setExpireTime(expireTime);
            String cacheinterview = objectmapper.writeValueAsString(cacheInterview);

            //将数据异步到el数据库当中
            String json = objectmapper.writeValueAsString(questionBank);
            redisTemplate.opsForHash().put(INTERVIEW_HASH_KEY,questionBank.getId().toString(),cacheinterview);

            log.info("异步发送数据到el数据库:{}",json);
            rabbitTemplate.convertAndSend(exchangeName,addRoutingKey,json);

        } catch (JsonProcessingException e) {
            throw new BaseException("添加面试问题异常");
        }
        return Result.success();
    }

    @DeleteMapping("/deleteQuestion/{id}")
    @Transactional
    public Result deleteQuestion(@PathVariable("id") Integer id){
        log.info("删除面试问题Id：{}",id);

        //延时双删
        redisTemplate.opsForHash().delete(INTERVIEW_HASH_KEY,id.toString());
        interviewQuestionsService.deleteQuestion(id);
        //删除缓存中对应的数据
        // 延时双删：异步执行第二次删除（延迟 1 秒）
        CompletableFuture.runAsync(() -> {
            try {
                TimeUnit.MILLISECONDS.sleep(1000); // 延时 1 秒
                redisTemplate.opsForHash().delete(INTERVIEW_HASH_KEY, id.toString());
                log.info("延时双删完成，ID: {}", id);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.error("延时双删被中断", e);
            } catch (Exception e) {
                log.error("延时双删失败", e);
            }
        });


        //如果zest热点数据中有这个数据、那么也要进行删除
        if (redisTemplate.opsForZSet().score(INTERVIEW_HOT_DATA, id.toString()) != null) {
            redisTemplate.opsForZSet().remove(INTERVIEW_HOT_DATA,id.toString());
        }
        //删除索引库中对应的数据
        rabbitTemplate.convertAndSend(exchangeName,deleteRoutingKey,id.toString());
        return Result.success();
    }

    @PutMapping("/updateQuestion")
    @Transactional
    public Result updateQuestion(@RequestBody QuestionBankDto questionBankDto){
        log.info("更新面试问题：{}",questionBankDto);
        try{
            QuestionBank questionBank = interviewQuestionsService.updateQuestion(questionBankDto);
            CacheInterview cacheInterview = new CacheInterview();
            cacheInterview.setQuestionBank(questionBank);
            long expireTime = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(2);
            cacheInterview.setExpireTime(expireTime);
            String question = objectmapper.writeValueAsString(cacheInterview);
            redisTemplate.opsForHash().put(INTERVIEW_HASH_KEY ,questionBankDto.getId().toString(),question);
            //更新索引库中对应的数据
            String questionbank = objectmapper.writeValueAsString(questionBank);
            rabbitTemplate.convertAndSend(exchangeName,updateRoutingKey,questionbank);
        }catch (Exception e){
            log.error("更新面试问题失败：{}",e);
            return Result.error("更新面试问题失败");
        }
        return Result.success();
    }

}
